/*
 * Create:      柿子
 * CreateDate:  2023/11/07
 * Describe：   滚动列表 - 溢出出现左右滑动的箭头左右切换滚动条宽度
 * */
import React from 'react';
import { Icon } from 'antd';
import '../style/index.less';

class ScrollList extends React.Component {
  constructor(props) {
    super(props);
    this.scrollContainerRef = React.createRef();
    this.state = {
      scrollPosition: 0,
      scrollTotalWidth: 0,
      currentScrollWidth: 0, // 当前滚动位置
      isOverFlowing: false,
      itemWidth: null,
    };
  }

  componentDidMount() {
    this.handleCheckOverflow();
    const element = this.scrollContainerRef?.current;
    const firstChildElement = element?.firstChild;
    if (firstChildElement) {
      const style = window.getComputedStyle(firstChildElement);
      const itemWidth = parseFloat(style.width);
      this.setState({ itemWidth, scrollTotalWidth: (element?.scrollWidth || 0) - (element?.offsetWidth || 0) });
    }
  };

  componentDidUpdate() {
    this.handleCheckOverflow();
  };

  handleCheckOverflow = () => {
    const element = this.scrollContainerRef?.current;
    if (element) {
      const isOverFlowing = element.offsetWidth < element.scrollWidth;
      if (isOverFlowing !== this.state.isOverFlowing) {
        this.setState({ isOverFlowing });
      }
    }
  };

  // 左移
  handleLeftClick = () => {
    if (this.scrollContainerRef && this.scrollContainerRef.current) {
      let newScrollPosition = Math.max(this.state.scrollPosition - this.scrollContainerRef.current.offsetWidth, 0);
      let slideTimer = setInterval(() => {
        if (this.scrollContainerRef.current.scrollLeft > newScrollPosition) {
          // 每次滚动10px, 如果剩余滚动距离不足10px，则滚动剩余距离
          let stepMove = Math.min(10, this.scrollContainerRef.current.scrollLeft - newScrollPosition);
          // 更新scrollLeft
          this.scrollContainerRef.current.scrollLeft -= stepMove;
        } else {
          clearInterval(slideTimer);
        }
      }, 0);
      // 更新state中保存的scroll position，以便下次点击时能正确计算newScrollPosition.
      this.setState({ scrollPosition: newScrollPosition, currentScrollWidth: (this.scrollContainerRef?.current?.scrollLeft || 0) - newScrollPosition });
    }
  };

  // 右移
  handleRightClick = () => {
    if (this.scrollContainerRef && this.scrollContainerRef.current) {
      let newScrollPosition = Math.min(
        this.state.scrollPosition + this.scrollContainerRef.current.offsetWidth,
        this.scrollContainerRef.current.scrollWidth - this.scrollContainerRef.current.offsetWidth
      );
      let scrollAmount = 0;
      let slideTimer = setInterval(() => {
        this.scrollContainerRef.current.scrollLeft += 10;
        scrollAmount += 10;
        if (scrollAmount >= newScrollPosition) {
          window.clearInterval(slideTimer);
        }
      }, 0);
      this.setState({ scrollPosition: newScrollPosition, currentScrollWidth: (this.scrollContainerRef?.current?.scrollLeft || 0) + newScrollPosition });
    }
  };

  render() {
    const { isOverFlowing, scrollTotalWidth, scrollPosition, currentScrollWidth } = this.state;
    return (
      <div className="flex-align-items scroll-list">
        {isOverFlowing && (
          <Icon
            type="left"
            className="scroll-list-arrow-left"
            style={{ cursor: scrollPosition === 0 ? 'no-drop' : 'pointer', color: scrollPosition === 0 ? '#00000040' : '#00000073' }}
            onClick={this.handleLeftClick}
          />
        )}
        <div ref={this.scrollContainerRef} className="scroll-container">
          {this.props.children}
        </div>
        {isOverFlowing && (
          <Icon
            type="right"
            className="scroll-list-arrow-right"
            style={{ cursor: currentScrollWidth >= scrollTotalWidth ? 'no-drop' : 'pointer', color: scrollPosition === scrollTotalWidth ? '#00000040' : '#00000073' }}
            onClick={this.handleRightClick}
          />
        )}
      </div>
    )
  }
}

export default ScrollList;